<?php

	/**
	 * PHP Road
	 *
	 * PHP application framework
	 *
	 * @package		PHPRoad
	 * @author		Aleksey Bobkov, Andy Chentsov
	 * @since		Version 1.0
	 * @filesource
	 */

	/**
	 * PHP Road Error Log Class
	 *
	 * Error log allows the application to write the error messages to a file.
	 *
	 * To enable the error logging set the ERROR_LOG value to true in the 
	 * application configuration file: $CONFIG['ERROR_LOG'] = true;
	 *
	 * By default the error log file (errors.txt) is situated in the application logs directory (logs/errors.txt).
	 * You may specify another location and the file name by setting the ERROR_LOG_FILE configuration parameter:
	 * $CONFIG['ERROR_LOG_FILE'] = "/home/logs/blogerrors.txt". In both cases the log file must be writable.
	 *
	 * PHP Road exceptions (the exceptions inherited from the Phpr_Exception class)
	 * logs themselves automatically. You may log the custom exception using the LogException() method.
	 *
	 * The instance of this class is available in the Phpr global object: Phpr::$errorLog.
	 *
	 * @see Phpr
	 *
	 * @package		PHPRoad
	 * @category	PHPRoad
	 * @author		Aleksey Bobkov
	 */
	class Phpr_ErrorLog
	{
		private $_logFileName;
		private $_isEnabled;
		private $_ignoreExceptions;
		
		public static $disable_db_logging = false;

		/**
		 * Creates a new Phpr_ErrorLog instance.
		 */
		public function __construct()
		{
			$this->loadConfiguration();
		}

		/**
		 * Writes an exception information to the log file.
		 * @param Exception $Exception Specifies the exception to log.
		 * @return boolean Returns true if exception was logged successfully.
		 */
		public function logException( Exception $Exception )
		{
			if ( !$this->_isEnabled )
				return false;

			foreach ( $this->_ignoreExceptions as $IgnoredExceptionClass )
			{
				if ( $Exception instanceof $IgnoredExceptionClass )
					return false;
			}
			
			if ($Exception instanceof Cms_ExecutionException)
				$Message = sprintf( "%s: %s. In %s, line %s", 
						get_class($Exception), 
						$Exception->getMessage(),
						'"'.$Exception->document_name().'" ('.$Exception->document_type().')',
						$Exception->code_line );
			else
				$Message = sprintf( "%s: %s. In %s, line %s", 
						get_class($Exception), 
						$Exception->getMessage(),
						$Exception->getFile(),
						$Exception->getLine() );
						
			$log_to_db = !($Exception instanceof Phpr_DatabaseException);
			
			$status = $this->writeLogMessage( $Message, $log_to_db );

			return $status;
		}

		/**
		 * Writes a message to the error log.
		 * You may override this method in the inherited class and write messages to a database table.
		 * @param string $Message A message to write.
		 * @param boolean $log_to_db Whether or not to log to the database.
		 * @return boolean Returns true if the message was logged successfully.
		 */
		protected function writeLogMessage( $Message, $log_to_db = true )
		{
			if (!class_exists('Phpr_LogHelper') && !Phpr::$classLoader->load('Phpr_LogHelper'))
				echo $Message;
			
			if ((Phpr::$config->get('LOG_TO_DB') || $this->_logFileName == null) && Db::$connection && !self::$disable_db_logging && $log_to_db)
			{
				if (!class_exists('Phpr_Trace_Log_Record') && !Phpr::$classLoader->load('Phpr_Trace_Log_Record'))
					return;
				
				Phpr_Trace_Log_Record::add( 'ERROR', $Message );
			}
			
			return Phpr_LogHelper::writeLine( $this->_logFileName, $Message );
		}

		/**
		 * Loads the error log configuration
		 */
		protected function loadConfiguration()
		{
			// Determine if the error log is enabled
			//
			$this->_isEnabled = Phpr::$config !== null && Phpr::$config->get( "ERROR_LOG", false );

			if ( $this->_isEnabled )
			{
				// Load the log file path
				//
				$this->_logFileName = Phpr::$config->get( "ERROR_LOG_FILE", PATH_APP."/logs/errors.txt" );

				// Check whether the file and directory are writable
				//
				if ( file_exists($this->_logFileName) )
				{
					if ( !is_writable($this->_logFileName) )
					{
						$exception = new Phpr_SystemException( 'The error log file is not writable: '.$this->_logFileName );
						$exception->hint_message = 'Please assign writing permissions on the error log file for the Apache user.';
						throw $exception;
					}
				}
				else
				{
					$directory = dirname($this->_logFileName);
					if ( !is_writable($directory) )
					{
						$exception = new Phpr_SystemException( 'The error log file directory is not writable: '.$directory );
						$exception->hint_message = 'Please assign writing permissions on the error log directory for the Apache user.';
						throw $exception;
					}
				}
			}

			// Load the ignored exceptions list
			//
			$this->_ignoreExceptions = Phpr::$config !== null ? Phpr::$config->get( "ERROR_IGNORE", array() ) : array();
		}
	}

?>